home *** CD-ROM | disk | FTP | other *** search
- page 66,132
- ; *****************************************************
- ; * PROLOG *
- ; * This is an installable device driver for an *
- ; * in storage diskette (virtual) with 180K capacity. *
- ; *****************************************************
- ;
- CSEG SEGMENT PARA PUBLIC 'CODE'
- ;
- ; M A C R O ( S )
- ;
- STATUS MACRO STATE,ERR,RC
- IFIDN <STATE>,<DONE>
- OR ES:WORD PTR SRH_STA_FLD[BX],0100H
- ENDIF
- IFIDN <STATE>,<BUSY>
- OR ES:WORD PTR SRH_STA_FLD[BX],0200H
- ENDIF
- IFIDN <ERR>,<ERROR>
- OR ES:WORD PTR SRH_STA_FLD[BX],1000H
- ENDIF
- IFNB <RC>
- OR ES:WORD PTR SRH_STA_FLD[BX],RC
- ENDIF
- ENDM
- ;
- ; E Q U A T E S
- ;
- ; READ/WRITE
- ;
- SRH EQU 0 ;
- SRH_LEN EQU 13 ;
- SRH_LEN_FLD EQU SRH ;
- SRH_UCD_FLD EQU SRH+1 ;
- SRH_CCD_FLD EQU SRH+2 ;
- SRH_STA_FLD EQU SRH+3 ;
- SRH_RES_FLD EQU SRH+5 ;
- ;
- MD EQU SRH+SRH_LEN ;
- MD_LEN EQU 1 ;
- DTA EQU MD+MD_LEN ;
- DTA_LEN EQU 4 ;
- COUNT EQU DTA+DTA_LEN ;
- COUNT_LEN EQU 2 ;
- SSN EQU COUNT+COUNT_LEN ;
- SSN_LEN EQU 2 ;
- ;
- ; MEDIA CHECK
- ;
- RET_BYTE EQU MD+MD_LEN ;
- ;
- ; BUILD BPB
- ;
- BPBA_PTR EQU DTA+DTA_LEN ;
- BPBA_PTR_LEN EQU 4 ;
- ;
- ; INIT
- ;
- UNITS EQU SRH+SRH_LEN
- UNITS_LEN EQU 1
- BR_ADDR_0 EQU UNITS+UNITS_LEN
- BR_ADDR_1 EQU BR_ADDR_0+2
- BR_ADDR_LEN EQU 4
- BPB_PTR_OFF EQU BR_ADDR_0+BR_ADDR_LEN
- BPB_PTR_SEG EQU BPB_PTR_OFF+2
- ;
- ;
- VDSK PROC FAR
- ASSUME CS:CSEG,ES:CSEG,DS:CSEG
- BEGIN:
- START EQU $
- ; S P E C I A L D E V I C E H E A D E R
- NEXT_DEV DD -1 ;
- ATTRIBUTE DW 2000H ;
- STRATEGY DW DEV_STRATEGY ;
- INTERRUPT DW DEV_INT ;
- DEV_NAME DB 3 ;
- DB 7 DUP(?) ;
- ;
- RH_OFF DW ? ;
- RH_SEG DW ? ;
- ; BIOS PARAMETER BLOCK
- BPB EQU $ ;
- SEC_SIZE DW 512 ;
- DB 1 ;
- DW 1 ;
- DB 1 ;
- DW 32 ;
- NUM_SEC DW 127 ; NOTE - must be less than 128
- DB 0FCH ; or arithmetic overflows.
- DW 1 ;
- ;
- BPB_PTR DW BPB ;
- DW BPB ;
- DW BPB ;
- ; CURRENT VIRTUAL DISK INFORMATION
- TOTAL DW ? ;
- VERIFY DB 0 ;
- START_SEC DW 0 ;
- VDISK_PTR DW 0 ;
- USER_DTA DD ? ;
- BOOT_REC EQU $ ;
- DB 3 DUP(0) ;
- DB 'IBM 2.0' ;
- DW 512 ;sector size
- DB 1 ;sectors per allocation unit
- DW 1 ;reserved sectors
- DB 1 ;FATS
- DW 32 ;directory entries
- DW 127 ;total sectors in image 127 tops
- DB 0FCH ;single sided 9 sector
- DW 1 ;sectors in FAT
- ;
- ; FUNCTION TABLE
- ;
- FUNTAB LABEL BYTE ;
- DW INIT ;
- DW MEDIA_CHECK ;
- DW BUILD_BPB ;
- DW IOCTL_IN ;
- DW INPUT ;
- DW ND_INPUT ;
- DW IN_STAT ;
- DW IN_FLUSH ;
- DW OUTPUT ;
- DW OUT_VERIFY ;
- DW OUT_FLUSH ;
- DW IOCTL_OUT ;
- ;
- ; L O C A L P R O C E D U R E S
- ;
- IN_SAVE PROC NEAR
- MOV AX,ES:WORD PTR DTA[BX]
- MOV CS:USER_DTA,AX
- MOV AX,ES:WORD PTR DTA+2[BX]
- MOV CS:USER_DTA+2,AX
- MOV AX,ES:WORD PTR COUNT[BX]
- XOR AH,AH
- MOV CS:TOTAL,AX
- RET
- IN_SAVE ENDP
- ;
- CALC_ADDR PROC NEAR
- MOV AX,CS:START_SEC
- MOV CX,20H
- MUL CX
- MOV DX,CS:VDISK_PTR
- ADD DX,AX
- MOV DS,DX
- XOR SI,SI
- MOV AX,CS:TOTAL
- MOV CX,512
- MUL CX
- OR AX,AX
- JNZ MOVE_IT
- MOV AX,0FFFFH
- MOVE_IT:
- XCHG CX,AX
- RET
- CALC_ADDR ENDP
- ;
- SECTOR_READ PROC NEAR
- CALL CALC_ADDR
- MOV ES,CS:USER_DTA+2
- MOV DI,CS:USER_DTA
- ;
- ; CHECK FOR DTA WRAP IN CASE WE CAME THROUGH VIA VERIFY
- ;
- MOV AX,DI
- ADD AX,CX
- JNC READ_COPY
- MOV AX,0FFFFH
- SUB AX,DI
- MOV CX,AX
- READ_COPY:
- REP MOVSB
- RET
- SECTOR_READ ENDP
- ;
- SECTOR_WRITE PROC NEAR
- CALL CALC_ADDR
- PUSH DS
- POP ES
- MOV DI,SI
- MOV DS,CS:USER_DTA+2
- MOV SI,CS:USER_DTA
- ;
- ; CHECK FOR DTA WRAP
- ;
- MOV AX,SI
- ADD AX,CX
- JNC WRITE_COPY
- MOV AX,0FFFFH
- SUB AX,SI
- MOV CX,AX
- WRITE_COPY:
- REP MOVSB
- RET
- SECTOR_WRITE ENDP
- ;
- ; D E V I C E S T R A T E G Y
- ;
- DEV_STRATEGY:
- MOV CS:RH_SEG,ES
- MOV CS:RH_OFF,BX
- RET
- ;
- ; D E V I C E I N T E R R U P T H A N D L E R
- ;
- DEV_INT:
- ;
- CLD
- PUSH DS
- PUSH ES
- PUSH AX
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH DI
- PUSH SI
- ;
- ;
- ; DO THE BRANCH ACCORDING TO THE FUNCTION PASSED
- ;
- MOV AL,ES:[BX]+2
- ROL AL,1
- LEA DI,FUNTAB
- XOR AH,AH
- ADD DI,AX
- JMP WORD PTR[DI]
- ;
- ; INIT
- ;
- INIT:
- PUSH CS
- POP DX
- LEA AX,CS:VDISK
- MOV CL,4
- ROR AX,CL
- ADD DX,AX
- MOV CS:VDISK_PTR,DX
- ;
- PUSH DX
- PUSH CX
- MOV AX,CS:SEC_SIZE
- MUL CS:NUM_SEC ; this limits us to 64kb disks
- MOV CL,4
- SHR AX,CL
- POP CX
- POP DX
- ;
- ADD DX,AX
- MOV ES:WORD PTR BR_ADDR_0[BX],0
- MOV ES:BR_ADDR_1[BX],DX
- ;
- ; find the number of disks on the machine and adjust
- ; "units" to make ram disks end with E:.
-
- PUSH AX
- PUSH DX
- MOV DL,0
- MOV AH,0EH
- INT 21H ;AL returns number of logical drives in system.
- MOV AH,5 ; put desired last vdisk in AH, A: = 1.
- SUB AH,AL
- POP DX
- MOV ES:BYTE PTR UNITS[BX],AH
- POP AX
- ;
- LEA DX,BPB_PTR
- MOV ES:BPB_PTR_OFF[BX],DX
- MOV ES:BPB_PTR_SEG[BX],CS
- MOV ES,CS:VDISK_PTR
- XOR DI,DI
- LEA SI,BOOT_REC
- MOV CX,24
- REP MOVSB
- MOV CS:WORD PTR START_SEC,1
- MOV CS:WORD PTR TOTAL,2
- CALL CALC_ADDR
- PUSH DS
- POP ES
- MOV DI,SI
- XOR AL,AL
- REP STOSB
- MOV DS:BYTE PTR [SI],0FCH
- MOV DS:BYTE PTR 1[SI],0FFH
- MOV DS:BYTE PTR 2[SI],0FFH
- PUSH DS
- PUSH SI
- MOV CS:WORD PTR START_SEC,3
- MOV CS:WORD PTR TOTAL,2
- CALL CALC_ADDR
- PUSH DS
- POP ES
- MOV DI,SI
- POP SI
- POP DS
- REP MOVSB
- MOV CS:WORD PTR START_SEC,5
- MOV CS:WORD PTR TOTAL,4
- CALL CALC_ADDR
- XOR AL, AL
- PUSH DS
- POP ES
- XOR DI,DI
- REP STOSB
- MOV ES,CS:RH_SEG
- MOV BX,CS:RH_OFF
- STATUS DONE,NOERROR,0
- OR ES:WORD PTR SRH_STA_FLD[BX],0100H
- OR ES:WORD PTR SRH_STA_FLD[BX],0
- JMP EXIT
- ;
- ; MEDIA CHECK
- ;
- MEDIA_CHECK:
- MOV ES:BYTE PTR RET_BYTE[BX],1
- STATUS DONE,NOERROR,0
- OR ES:WORD PTR SRH_STA_FLD[BX],0100H
- OR ES:WORD PTR SRH_STA_FLD[BX],0
- JMP EXIT
- ; BUILD BIOS PARAMETER BLOCK
- ;
- BUILD_BPB:
- PUSH ES
- PUSH BX
- MOV CS:WORD PTR START_SEC,0
- MOV CS:WORD PTR TOTAL,1
- CALL CALC_ADDR
- PUSH CS
- POP ES
- LEA DI,BPB
- ADD SI,11
- MOV CX,13
- REP MOVSB
- POP BX
- POP ES
- LEA DX,BPB
- MOV ES:BPBA_PTR[BX],DX
- MOV ES:BPBA_PTR+2[BX],CS
- MOV ES:DTA[BX],DX
- MOV ES:DTA+2[BX],CS
- STATUS DONE,NOERROR,0
- OR ES:WORD PTR SRH_STA_FLD[BX],0100H
- OR ES:WORD PTR SRH_STA_FLD[BX],0
- JMP EXIT
- ;
- ; THE FOLLOWING ENTRIES ARE FOR NOT SUPPORTED BY THIS DEVICE
- ;
- IOCTL_IN:
- IOCTL_OUT:
- ND_INPUT:
- IN_STAT:
- IN_FLUSH:
- OUT_STAT:
- OUT_FLUSH:
- ;
- ; DISK READ
- ;
- INPUT:
-
- CALL IN_SAVE
- MOV AX,ES:WORD PTR SSN[BX]
- MOV CS:START_SEC,AX
- MOV AX,ES:WORD PTR COUNT[BX]
- MOV CS:TOTAL,AX
- CALL SECTOR_READ
- MOV BX,CS:RH_OFF
- MOV ES,CS:RH_SEG
- STATUS DONE,NOERROR,0
- OR ES:WORD PTR SRH_STA_FLD[BX],0100H
- OR ES:WORD PTR SRH_STA_FLD[BX],0
-
- JMP EXIT
- ;
- ; DISK WRITE
- ;
- OUTPUT:
- CALL IN_SAVE
- MOV AX,ES:WORD PTR SSN[BX]
- MOV CS:START_SEC,AX
- MOV AX,ES:WORD PTR COUNT[BX]
- MOV CS:TOTAL,AX
- CALL SECTOR_WRITE
- MOV BX,CS:RH_OFF
- MOV ES,CS:RH_SEG
- CMP CS:BYTE PTR VERIFY,0
- JZ NO_VERIFY
- MOV CS:BYTE PTR VERIFY,0
- JMP INPUT
- NO_VERIFY:
- STATUS DONE,NOERROR,0
- OR ES:WORD PTR SRH_STA_FLD[BX],0100H
- OR ES:WORD PTR SRH_STA_FLD[BX],0
- JMP EXIT
- OUT_VERIFY:
- MOV CS:BYTE PTR VERIFY,1
- JMP OUTPUT
- ;
- ; COMMON EXIT
- ;
- EXIT:
- POP SI
- POP DI
- POP DX
- POP CX
- POP BX
- POP AX
- POP ES
- POP DS
- RET
- E_O_P:
- ; MACRO TO ALIGN THE VIRTUAL DISK ON A PARAGRAPH BOUNDRY
- if ($-START) MOD 16
- ORG ($-START)+16-(($-START) MOD 16)
- endif
- VDISK EQU $
- VDSK ENDP
- CSEG ENDS
- END BEGIN
-